#include "stdafx.h"
#include "unit_io.h"

///Read string from file and fix 0A character in the end if any
char * read_string_raw (char *buffer, int size, FILE *file)
{
	char *result;
	if((result=fgets(buffer,size,file))!=NULL)
		if(strlen(buffer)>0)
			if(buffer[strlen(buffer)-1]==10)
				buffer[strlen(buffer)-1]=0;
	return result;
}

//////////////////////////////////////////////////////////Base io-functions for unit-testing
///Reading input arguments
int readInt(FILE *file)
{
	int res; char buffer[100];
	fgets(buffer,100,file);
	res=atoi(buffer);
	return res;
}
int readInt1D(FILE *file, int *arr, int size)
{
	int real_size=readInt(file);
	if(size<real_size)
	{
		return _READ_INVALID_ARRAY_TOO_LARGE;
	}
	char buffer[300];
	read_string_raw(buffer,300,file);
	char tokens[100][10];
	int actual_size=parse_string<100,10>(buffer," ",tokens);
	if(actual_size!=real_size)
	{
		return _READ_INVALID_ARRAY_CONTENT_DIFFER_FROM_COUNT;
	}
	for(int i=0;i<real_size;i++)
		arr[i]=atoi(tokens[i]);
	return real_size;

}
void readString(FILE *file, char *buffer, int size)
{
	read_string_raw(buffer,size,file);
}
char readChar(FILE *file)
{
	char buffer[10];
	read_string_raw(buffer,10,file);
	return buffer[0];
}

///Writing output arguments
void writeInt(FILE *file,int number)
{
	fprintf(file,"%d\n",number);
}
void writeFloat(FILE *file,float number)
{
	fprintf(file,"%g\n",number);
}
void writeInt1D(FILE *file,const int *arr, int size)
{
	if(size==0)
		fprintf(file,"|||empty|||\n");
	else
	{
		for(int i=0;i<size;i++)
			fprintf(file,"%d ",arr[i]);
		fprintf(file,"\n");
	}
}
void writeFloat1D(FILE *file,const float *arr, int size)
{
	if(size==0)
		fprintf(file,"|||empty|||\n");
	else
	{
		for(int i=0;i<size;i++)
			fprintf(file,"%g ",arr[i]);
		fprintf(file,"\n");
	}
}
void writeString(FILE *file, const char *string)
{
	if(string[0]==0)
		fprintf(file,"|||empty|||\n");
	else
		fprintf(file,"%s\n",string);
}
void writeOutArg(FILE *file,const  char *arg)
{
	fprintf(file,"[out]>>%s\n",arg);
}

//word pointer classes functions

char wordPointer::err_desc[20][100] = {
		"ERROR: Start position must be before end position\n",
		"ERROR: Word length differs from start-end\n",
		"ERROR: Pointer or index miss the string\n",
		"ERROR: Word length too long for this string and start\n",
		"ERROR: Pointer or index miss the text\n",
		"ERROR: Start and end pointers are expected to point in the one string\n"
	};

char wordPointer1D::arg_title[55] = "begin - end => word";
char wordPointer2D::arg_title[55] = "(LineBegin, ColBegin) - (LineEnd, ColEnd) => word";

void wordPointer1D::read(FILE *file)
{
	fscanf(file,"%d %d ",&start,&end);
	readString(file,word,100);
	if(start>end)
	{
		error=_PTR_ERROR_START_AFTER_END;
		return;
	}
	if(strlen(word)!=end-start)
	{
		error=_PTR_ERROR_WRONG_WORD_LENGTH;
	}
}
void wordPointer1D::write(FILE *file) const
{
	fprintf(file,"%d - %d => %s\n",start, end, word);
}

int wordPointer1D::extractFromPairOfPtrs(char *string, char *ptrStart, char *ptrEnd)
{ 
	int strLen=strlen(string);

	if(ptrStart>ptrEnd)
	{
		error=_PTR_ERROR_START_AFTER_END;
		return 0;
	}
	if(ptrStart < string || ptrStart > string+strLen || ptrEnd < string || ptrEnd > string+strLen)
	{
		error=_PTR_POINTER_MISS_THE_STRING;
		return 0;
	}

	start=ptrStart-string;
	end=ptrEnd-string;
	strncpy(word,ptrStart,ptrEnd-ptrStart+1);
	word[end-start+1]=0;
	return 1;
}
int wordPointer1D::extractFromPtrAndLen(char *string, char*ptrStart, int len)
{
	int strLen=strlen(string);

	if(ptrStart < string || ptrStart > string+strLen)
	{
		error=_PTR_POINTER_MISS_THE_STRING;
		return 0;
	}
	if(ptrStart+len > string+strLen)
	{
		error=_PTR_WORD_TOO_LONG;
		return 0;
	}

	start=ptrStart-string;
	end=start+len-1;
	strncpy(word,ptrStart,len);
	word[len]=0;
	return  1;
}

void wordPointer2D::read(FILE *file)
{
	fscanf(file,"%d %d %d %d",&lineStart, &colStart, &lineEnd, &colEnd);
	readString(file,word,100);
	//TODO write checks if this function will ever be used in real situation
}
void wordPointer2D::write(FILE *file) const
{
	fprintf(file,"(%d,%d) - (%d,%d) => %s\n",lineStart, colStart, lineEnd, colEnd, word);
}
